
package cn.org.seventh.common;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.util.Random;

/**
 * @author <a href="mailto:ji.li@symbio-group.com">Andy</a>
 * @since Nov 30, 2007 4:18:14 PM
 */
public class VerifyCodeImage {

    private static final int FONT_SIZE = 14;

    private static final int HEIGHT = 20;

    private static final int WIDTH = 70;

    private static final int FONT_WIDTH = 18;

    private static final int OFFSET_X = 2;

    BufferedImage bi =
        new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);

    public VerifyCodeImage(String s) {
        Graphics2D g = (Graphics2D) bi.getGraphics();
        Color color = Color.BLACK;
        Color bgColor = Color.WHITE;
        g.setColor(bgColor);
        g.fillRect(0, 0, WIDTH, HEIGHT);
        Random random = new Random();
        for (int i = 0; i < 100; i++) {
            int x = random.nextInt(WIDTH);
            int y = random.nextInt(HEIGHT);
            int xl = random.nextInt(3);
            int yl = random.nextInt(3);
            g.setColor(getRandColor(230, 240));
            g.drawLine(x, y, x + xl, y + yl);
        }
        Font f = new Font("Times New Roman", Font.BOLD, FONT_SIZE);
        g.drawImage(getCharImage(s.toCharArray(), 0, 1, FONT_WIDTH, HEIGHT, f,
            color, bgColor), OFFSET_X, 0, null);
        g.drawImage(getCharImage(s.toCharArray(), 1, 1, FONT_WIDTH, HEIGHT, f,
            color, bgColor), WIDTH / 4 + OFFSET_X, 0, null);
        g.drawImage(getCharImage(s.toCharArray(), 2, 1, FONT_WIDTH, HEIGHT, f,
            color, bgColor), 2 * (WIDTH / 4) + OFFSET_X, 0, null);
        g.drawImage(getCharImage(s.toCharArray(), 3, 1, FONT_WIDTH, HEIGHT, f,
            color, bgColor), 3 * (WIDTH / 4) + OFFSET_X, 0, null);
        g.dispose();
    }

    public BufferedImage getCharImage(char[] chars, int start, int length,
                                      int width, int height, Font f,
                                      Color color, Color bgColor) {
        BufferedImage ci =
            new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g = (Graphics2D) ci.getGraphics();
        RenderingHints rhs = g.getRenderingHints();
        rhs.put(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
        g.setRenderingHints(rhs);
        g.setColor(color);
        g.setFont(f);
        double r = 0.20 - Math.random() * 0.4;
        AffineTransform aft = new AffineTransform();
        aft.setToRotation(r, 0, 0);
        g.setTransform(aft);
        g.drawChars(chars, start, length,
            (int) (2.5 + Math.abs(r * r * 1.5) * 10), (int) (height - 4 - Math
                .abs(r) * 6));
        g.dispose();
        return ci;
    }

    public BufferedImage getImage() {
        return bi;
    }

    protected Random random = new Random();

    Color getRandColor(int fc, int bc) {
        if (fc > 255)
            fc = 255;
        if (bc > 255)
            bc = 255;
        int r = fc + random.nextInt(bc - fc);
        int g = r;
        int b = r;
        return new Color(r, g, b);
    }
}
